#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>

struct student
{
	int MT;//数学
    int EN;//英语
	int PH;//物理
	int num;//学号	
	char name[10];//姓名
	int sum;	//总分
	double ave;	//平均分
}stu[30];

int check(char [],int );//检查是否右重复
void cover(struct student );//覆盖重复的数据
void set_score(int ,char []);//成绩录入
//显示信息
void display(void);
void input(void);
void search(void);

int main()
{
    int f,flag;//f判断菜单，flag检查正确性
    while(1)
	{
        do{
		    printf("1.录入学生成绩  2.输出所有学生成绩  3.搜索某学生成绩\n:>");
		    flag=scanf("%d",&f);
            getchar();
        }while(flag!=1);
		switch (f)
        	{
            		case 1:input();break;
            		case 2:display();break;
		            case 3:search();break;	
                    default:printf("没有该命令!\n");
        	}
	}
	return 0;

}


void input()
{
    char ch;
    FILE *fp;
    int i=0,f=0;//i第几个学生
	int n;//n记录次数
	do{
		printf("输入人数:");
		scanf("%d",&n);
	}while(n>30);
	while(i<n)
	{
		printf("输入姓名:");
		scanf("%s",stu[i].name);
        getchar();      //接收键盘缓存
		printf("输入学号:");
		scanf("%d",&stu[i].num);
        getchar();      //接收键盘缓存
        f=check(stu[i].name,stu[i].num);//判断是否右重复
        if(f==1||f==2){
            if(f==1)
                printf("姓名重复!\n覆盖?(y:n):");
            if(f==2)
                printf("学号重复!\n覆盖?(y:n):");
            do{
                ch=getchar();
                if(ch=='y'||ch=='Y'){
                    set_score(i,"unnormal");//录入成绩
                    i++;
                    break;
                }
                if(ch=='n'||ch=='N'){
                    continue;
                }
            }while(ch!='n'||ch!='N'||ch!='Y'||ch!='y');//当输入不是y或n时继续输入
            break;
        }
        set_score(i,"normal");
		i++;
        f=0;
	}

}

//检查是否重复函数
int check(char na[],int n)
{
    struct student stu2[30];
    int i;
    FILE *fp;
    fp=fopen("date.dat","rb");
    for(i=0;!feof(fp);i++){
        fread(&stu2[i],sizeof(struct student),1,fp);
        if(strcmp(stu2[i].name,na)==0){
            fclose(fp);
            return 1;
        }
        if(stu2[i].num==n){
            fclose(fp);
            return 2;
        }
    }
    fclose(fp);
    return 0;
}


//覆盖原来的数据
void cover(struct student stuJudge)
{
    printf("ok\n");
    int t=0,i;
    FILE *fp;
    struct student stu3[30],temp[30];

    fp=fopen("date.dat","rb");
    for(i=0;!feof(fp);i++){
        fread(&temp[i],sizeof(struct student),1,fp);//读取磁盘数据
        if(strcmp(temp[i].name,stuJudge.name)==0)     //把重复的数据覆盖
        {
            stu3[i]=stuJudge;
        
        }
        else{
            stu3[i]=temp[i];
        }
        t++;
    }
    t--;
    fclose(fp);

    fp=fopen("date.dat","wb");  //把提取出来的数据重写到磁盘
    for(i=0;i<t;i++){
        fwrite(&stu3[i],sizeof(struct student),1,fp);
    }
    fclose(fp);
}

//成绩录入函数
void set_score(int i,char f[])
{
    FILE *fp;
    
	printf("输入数学成绩:");
	scanf("%d",&stu[i].MT);
	printf("输入英语成绩:");
	scanf("%d",&stu[i].EN);
	printf("输入物理成绩:");
	scanf("%d",&stu[i].PH);
	stu[i].sum=stu[i].MT+stu[i].EN+stu[i].PH;//求和
	stu[i].ave=(double)stu[i].sum/3;//求平均

    //写数据进磁盘
    if(f=="normal"){
        fp=fopen("date.dat","ab");
        fwrite(&stu[i],sizeof(struct student),1,fp);
        fclose(fp);
    }
    if(f=="unnormal"){
        cover(stu[i]);
    }
}

//显示信息
void display()
{
    FILE *fp;
    int t,j,n,i;
	struct student stu2[30],temp;//定义30个结构体,temp用作交换
//----------------------读取磁盘数据-------------------//
    fp=fopen("date.dat","rb");
    for(t=0;!feof(fp);t++){
        fread(&stu2[t],sizeof(struct student),1,fp);
    }
    t--; 
    fclose(fp);


//---------------排序-------------------------------------------------//
	for(j=0;j<t-1;j++)	
		for(i=0;i<t-1-j;i++){
			if(stu2[i].sum<stu2[i+1].sum){
				temp=stu2[i];
				stu2[i]=stu2[i+1];
				stu2[i+1]=temp;	
			}
		}


//---------------------输出-------------------------------//
	printf("\n");
	for(i=0;i<t;i++)	//输出名次
		printf("第%d名:%s\n",i+1,stu2[i].name);
	printf("\n------------------------------------------------------\n");	//输出列表
	printf("学生编号 | 姓名 | 英语 | 数学 | 物理 | 总分 | 平均分 |\n");
	for(i=0;i<t;i++){
		printf("------------------------------------------------------\n");
		printf(" %-8d| %-5s| %-5d| %-5d| %-5d| %-5d| %-7.2lf|\n",stu2[i].num,stu2[i].name,stu2[i].EN,stu2[i].MT,stu2[i].PH,stu2[i].sum,stu2[i].ave);
	}

	printf("------------------------------------------------------\n");
	
	
}

//搜索函数
void search()
{
    FILE *fp;
	int n,flag=0,i;
    struct student stu2[30];
	printf("\n输入学生编号:");
	scanf("%d",&n);
    fp=fopen("date.dat","rb");
	for(i=0;!feof(fp);i++){
        fread(&stu2[i],sizeof(struct student),1,fp);
		if(n==stu2[i].num){
			printf("姓名:%s\n英语:%d\n数学:%d\n物理:%d\n总分:%d\n平均分:%.2lf\n",stu2[i].name,stu2[i].EN,stu2[i].MT,stu2[i].PH,stu2[i].sum,stu2[i].ave);
			flag=1;
			break;
		}
	}
    fclose(fp);
    if(flag!=1)printf("未找到该学号!\n");
    flag=0;
}


